package com.ize.service.impl;

import com.alibaba.fastjson.JSON;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;

import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.ize.entity.dto.*;
import com.ize.entity.pojo.DoctorCom;
import com.ize.entity.pojo.Reservation;
import com.ize.entity.pojo.User;
import com.ize.mapper.UserMapper;
import com.ize.mapper.YuYueMapper;
import com.ize.service.YuYueService;
import com.ize.util.BaseContext;
import com.ize.websocket.WebSocketServer;
import lombok.RequiredArgsConstructor;
import org.springframework.beans.BeanUtils;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.LocalTime;
import java.time.format.DateTimeFormatter;
import java.util.*;
import java.util.stream.Collectors;

@Service
@RequiredArgsConstructor
public class YuYueServiceImpl extends ServiceImpl<YuYueMapper, Reservation> implements YuYueService {

    // 定义默认的可预约时间段
    private static final List<String> ALL_TIME_SLOTS = Arrays.asList(
            "08:00", "08:30", "09:00", "09:30", "10:00", "10:30", "11:00", "11:30",
            "14:00", "14:30", "15:00", "15:30", "16:00", "16:30", "17:00", "17:30"
    );
    private final YuYueMapper yuYueMapper;
    private final UserMapper userMapper;
    private final WebSocketServer webSocketServer;

    /**
     * 分页查询预约列表
     */
    @Override
    public Page<Reservation> getReservationPage(ReservationQueryDTO query) {
        Page<Reservation> page = new Page<>(query.getPage(), query.getPageSize());
        return baseMapper.selectByCondition(page, query ,BaseContext.getCurrentId());
    }

    /**
     * 根据ID获取预约详情
     */
    @Override
    public Reservation getReservationById(Long id) {
        return getById(id);
    }

    /**
     * 创建预约
     */
    @Override
    @Transactional
    public boolean createReservation(Reservation reservation) {
        // 设置默认状态为待确认
        if (reservation.getStatus() == null || reservation.getStatus().isEmpty()) {
            reservation.setStatus("PENDING");
        }

        // 设置创建时间和更新时间
        LocalDateTime now = LocalDateTime.now();
        reservation.setCreateTime(now);
        reservation.setUpdateTime(now);

        return save(reservation);
    }

    /**
     * 更新预约信息
     */
    @Override
    @Transactional
    public boolean updateReservation(Long id, Reservation reservation) {
        // 验证预约是否存在
        Reservation existingReservation = getById(id);
        if (existingReservation == null) {
            return false;
        }

        // 设置ID和更新时间
        reservation.setId(id);
        reservation.setUpdateTime(LocalDateTime.now());

        return updateById(reservation);
    }

    /**
     * 更新预约状态
     */
    @Override
    @Transactional
    public boolean updateReservationStatus(Long id, String status, String remark) {
        // 验证预约是否存在
        Reservation existingReservation = getById(id);
        if (existingReservation == null) {
            return false;
        }

        // 更新状态和备注
        existingReservation.setStatus(status);
        if (remark != null && !remark.isEmpty()) {
            existingReservation.setRemark(remark);
        }
        existingReservation.setUpdateTime(LocalDateTime.now());

        return updateById(existingReservation);
    }

    /**
     * 删除预约
     */
    @Override
    @Transactional
    public boolean deleteReservation(Long id) {
        return removeById(id);
    }

    /**
     * 批量操作预约
     */
    @Override
    @Transactional
    public boolean batchOperateReservation(BatchOperationDTO batchOperation) {
        if (batchOperation.getIds() == null || batchOperation.getIds().isEmpty() || batchOperation.getAction() == null) {
            return false;
        }

        // 根据操作类型设置状态
        String status;
        switch (batchOperation.getAction()) {
            case "confirm":
                status = "CONFIRMED";
                break;
            case "cancel":
                status = "CANCELLED";
                break;
            case "complete":
                status = "COMPLETED";
                break;
            default:
                return false;
        }

        // 批量更新状态
        List<Reservation> reservations = listByIds(batchOperation.getIds());
        LocalDateTime now = LocalDateTime.now();

        for (Reservation reservation : reservations) {
            reservation.setStatus(status);
            reservation.setUpdateTime(now);
        }

        return updateBatchById(reservations);
    }

    /**
     * 获取可用预约时间段
     */
    @Override
    public List<String> getAvailableTimeSlots(AvailableSlotsQueryDTO query) {
        if (query.getDoctorId() == null || query.getDate() == null || query.getDate().isEmpty()) {
            return Collections.emptyList();
        }

        // 解析日期
        DateTimeFormatter dateFormatter = DateTimeFormatter.ofPattern("yyyy-MM-dd");
        LocalDate date = LocalDate.parse(query.getDate(), dateFormatter);
        LocalDateTime dateTime = date.atStartOfDay();

        // 获取已占用的时间段
        List<String> occupiedSlots = baseMapper.getOccupiedTimeSlots(
                query.getDoctorId(), dateTime, query.getCurrentAppointmentId());

        // 返回可用时间段（所有时间段减去已占用的）
        return ALL_TIME_SLOTS.stream()
                .filter(slot -> !occupiedSlots.contains(slot))
                .collect(Collectors.toList());
    }

    /**
     * 获取预约统计数据
     */
    @Override
    public ReservationStatisticsDTO getStatistics(String startDate, String endDate, Long doctorId) {
        LocalDateTime startTime = null;
        LocalDateTime endTime = null;

        // 解析日期范围
        if (startDate != null && !startDate.isEmpty()) {
            startTime = LocalDate.parse(startDate).atTime(0, 0, 0);
        }

        if (endDate != null && !endDate.isEmpty()) {
            endTime = LocalDate.parse(endDate).atTime(23, 59, 59);
        }

        // 准备返回数据
        ReservationStatisticsDTO result = new ReservationStatisticsDTO();

        // 获取状态统计
        Map<String, Long> statusCounts = baseMapper.countByStatus(startTime, endTime, doctorId);
        if (statusCounts != null) {
            result.setTotal(convertToLong(statusCounts.get("total")));
            result.setPendingCount(convertToLong(statusCounts.get("pendingCount")));
            result.setConfirmedCount(convertToLong(statusCounts.get("confirmedCount")));
            result.setCancelledCount(convertToLong(statusCounts.get("cancelledCount")));
            result.setCompletedCount(convertToLong(statusCounts.get("completedCount")));
            result.setRescheduledCount(convertToLong(statusCounts.get("rescheduledCount")));
        }

        // 获取科室分布
        List<Map<String, Object>> deptData = baseMapper.countByDept(startTime, endTime, doctorId);
        if (deptData != null) {
            List<ReservationStatisticsDTO.DeptDistribution> deptDistribution = new ArrayList<>();

            for (Map<String, Object> data : deptData) {
                ReservationStatisticsDTO.DeptDistribution item = new ReservationStatisticsDTO.DeptDistribution();
                item.setName((String) data.get("name"));
                item.setValue(convertToLong(data.get("value")));
                deptDistribution.add(item);
            }

            result.setDeptDistribution(deptDistribution);
        }

        // 获取时间分布
        List<Map<String, Object>> timeData = baseMapper.countByDate(startTime, endTime, doctorId);
        if (timeData != null) {
            List<ReservationStatisticsDTO.TimeDistribution> timeDistribution = new ArrayList<>();

            for (Map<String, Object> data : timeData) {
                ReservationStatisticsDTO.TimeDistribution item = new ReservationStatisticsDTO.TimeDistribution();
                item.setDate((String) data.get("date"));
                item.setCount(convertToLong(data.get("count")));
                timeDistribution.add(item);
            }

            result.setTimeDistribution(timeDistribution);
        }

        return result;
    }

    /**
     * 安全地将Number类型（包括BigDecimal）转换为Long
     */
    private Long convertToLong(Object value) {
        if (value == null) {
            return 0L;
        }
        if (value instanceof Number) {
            return ((Number) value).longValue();
        }
        return 0L;
    }

    /**
     * 学生预约
     * @param addStudentYuYueDto
     */
    @Override
    @Transactional
    public void add(addStudentYuYueDto addStudentYuYueDto) {
        //先从user表获取用户信息
        User user = userMapper.selectById(BaseContext.getCurrentId());

        Reservation reservation = new Reservation();
        BeanUtils.copyProperties(addStudentYuYueDto, reservation);
        reservation.setPatientName(user.getUsername());
        reservation.setPatientAge(user.getAge());
        reservation.setPatientPhone(user.getPhone());
        reservation.setCreateTime(LocalDateTime.now());
        reservation.setUpdateTime(LocalDateTime.now());

        //先存数据
        yuYueMapper.insert(reservation);

        //调 webSocket
        //用websocket 建立客户端连接和推送消息
        Map hashMap = new HashMap();
        hashMap.put("patient_name",user.getUsername());
        hashMap.put("gender",user.getSex());
        hashMap.put("time",LocalDateTime.now());

        //把信息转成Json字符转
        String jsonString = JSON.toJSONString(hashMap);
        System.out.println(jsonString);
        webSocketServer.sendToAllClient(jsonString);
    }

    @Override
    public List<Reservation> getYu() {
        User user = userMapper.selectById(BaseContext.getCurrentId());
        QueryWrapper<Reservation> wrapper = Wrappers.query();
        wrapper.eq("patient_name",user.getUsername());
        List<Reservation> doctorComs = yuYueMapper.selectList(wrapper);
        return doctorComs;
    }

    @Override
    public void delete(Integer id) {
        yuYueMapper.deleteById(id);
    }
}
